package com.team9.fitness.service;

import com.team9.fitness.entity.ExerciseInfo;
import com.team9.fitness.entity.ExerciseRecord;
import com.team9.fitness.mapper.ExerciseRecordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 运动记录管理服务类
 * 
 * 提供运动记录的核心业务逻辑：
 * - 开始运动：支持单用户同时只能进行一项运动
 * - 结束运动：记录运动时长、心率、速度等数据
 * - 查询记录：支持按用户、状态、时间范围查询
 * - 健康监控：集成心率健康状态评估
 * 
 * 业务规则：
 * - 同一用户同时只能进行一项运动
 * - 运动结束后自动计算时长
 * - 支持心率、速度等运动数据记录
 */
@Service
@Transactional
@Slf4j
public class ExerciseRecordService {

    @Autowired
    private ExerciseRecordMapper exerciseRecordMapper;

    @Autowired
    private ExerciseInfoService exerciseInfoService;

    /**
     * 开始运动
     */
    public ExerciseRecord startExercise(ExerciseRecord exerciseRecord) {
        // 验证运动信息
        ExerciseInfo exerciseInfo = exerciseInfoService.getExerciseInfoById(exerciseRecord.getExerciseId());
        if (exerciseInfo == null) {
            throw new RuntimeException("运动信息不存在");
        }

        // 检查用户是否已有进行中的运动
        List<ExerciseRecord> ongoingRecords = exerciseRecordMapper.selectByUserIdAndStatus(exerciseRecord.getUserId(),
                "进行中");
        if (!ongoingRecords.isEmpty()) {
            throw new RuntimeException("请先结束当前运动");
        }

        // 设置开始时间和状态
        exerciseRecord.setExerciseName(exerciseInfo.getName()); // 设置运动名称
        exerciseRecord.setStartTime(LocalDateTime.now());
        exerciseRecord.setStatus("进行中");
        exerciseRecord.setCreatedAtIfNull();

        exerciseRecordMapper.insert(exerciseRecord);

        return exerciseRecord;
    }

    /**
     * 结束运动
     */
    public ExerciseRecord endExercise(Long recordId, Double avgHeartRate, Double maxHeartRate,
            Double avgSpeed, Double maxSpeed) {
        try {
            log.info("开始结束运动: recordId={}, avgHeartRate={}, maxHeartRate={}, avgSpeed={}, maxSpeed={}",
                    recordId, avgHeartRate, maxHeartRate, avgSpeed, maxSpeed);

            ExerciseRecord record = exerciseRecordMapper.selectById(recordId);
            if (record == null) {
                log.error("运动记录不存在: recordId={}", recordId);
                throw new RuntimeException("运动记录不存在");
            }

            if (!"进行中".equals(record.getStatus())) {
                log.error("运动记录状态不正确: recordId={}, status={}", recordId, record.getStatus());
                throw new RuntimeException("运动记录状态不正确");
            }

            // 设置结束时间和状态
            record.setEndTime(LocalDateTime.now());
            record.setStatus("已完成");
            record.setAvgHeartRate(avgHeartRate);
            record.setMaxHeartRate(maxHeartRate);
            record.setAvgSpeed(avgSpeed);
            record.setMaxSpeed(maxSpeed);

            // 计算运动时长
            record.calculateDuration();

            log.info("运动记录更新前: recordId={}, startTime={}, endTime={}, durationSeconds={}",
                    recordId, record.getStartTime(), record.getEndTime(), record.getDurationSeconds());

            int updateResult = exerciseRecordMapper.update(record);
            if (updateResult <= 0) {
                log.error("更新运动记录失败: recordId={}, updateResult={}", recordId, updateResult);
                throw new RuntimeException("更新运动记录失败");
            }

            log.info("运动记录更新成功: recordId={}", recordId);

            return record;
        } catch (Exception e) {
            log.error("结束运动失败: recordId={}, error={}", recordId, e.getMessage(), e);
            throw e;
        }
    }

    /**
     * 根据ID获取运动记录
     */
    public ExerciseRecord getExerciseRecordById(Long id) {
        return exerciseRecordMapper.selectById(id);
    }

    /**
     * 获取用户的所有运动记录
     */
    public List<ExerciseRecord> getExerciseRecordsByUserId(Long userId) {
        return exerciseRecordMapper.selectByUserId(userId);
    }

    /**
     * 获取用户指定状态的运动记录
     */
    public List<ExerciseRecord> getExerciseRecordsByUserIdAndStatus(Long userId, String status) {
        return exerciseRecordMapper.selectByUserIdAndStatus(userId, status);
    }

    /**
     * 获取用户指定日期的运动记录
     */
    public List<ExerciseRecord> getExerciseRecordsByUserIdAndDate(Long userId, LocalDateTime date) {
        return exerciseRecordMapper.selectByUserIdAndDate(userId, date);
    }

    /**
     * 获取用户指定运动的记录
     */
    public List<ExerciseRecord> getExerciseRecordsByUserIdAndExerciseId(Long userId, Long exerciseId) {
        return exerciseRecordMapper.selectByUserIdAndExerciseId(userId, exerciseId);
    }

    /**
     * 删除运动记录
     */
    public void deleteExerciseRecord(Long id) {
        exerciseRecordMapper.deleteById(id);
    }

    /**
     * 开始运动业务逻辑（供ZRDDS调用）
     */
    public ExerciseRecord startExerciseByZRDDS(Long userId, Long exerciseId) {
        try {
            // 验证运动信息
            ExerciseInfo exerciseInfo = exerciseInfoService.getExerciseInfoById(exerciseId);
            if (exerciseInfo == null) {
                log.warn("运动信息不存在: exerciseId={}", exerciseId);
                return null;
            }

            // 检查用户是否已有进行中的运动
            List<ExerciseRecord> ongoingRecords = exerciseRecordMapper.selectByUserIdAndStatus(userId, "进行中");
            if (!ongoingRecords.isEmpty()) {
                log.warn("用户已有进行中的运动: userId={}", userId);
                return null;
            }

            // 创建运动记录
            ExerciseRecord exerciseRecord = new ExerciseRecord();
            exerciseRecord.setUserId(userId);
            exerciseRecord.setExerciseId(exerciseId);
            exerciseRecord.setExerciseName(exerciseInfo.getName()); // 设置运动名称
            exerciseRecord.setStartTime(LocalDateTime.now());
            exerciseRecord.setStatus("进行中");
            exerciseRecord.setCreatedAtIfNull();

            exerciseRecordMapper.insert(exerciseRecord);
            log.info("开始运动成功: recordId={}, userId={}, exerciseId={}", exerciseRecord.getId(), userId, exerciseId);
            return exerciseRecord;
        } catch (Exception e) {
            log.error("开始运动失败: userId={}, exerciseId={}", userId, exerciseId, e);
            return null;
        }
    }

    /**
     * 结束运动业务逻辑（供ZRDDS调用）
     */
    public ExerciseRecord endExerciseByZRDDS(Long recordId, Double avgHeartRate, Double maxHeartRate, Double avgSpeed,
            Double maxSpeed) {
        try {
            ExerciseRecord record = exerciseRecordMapper.selectById(recordId);
            if (record == null) {
                log.warn("运动记录不存在: recordId={}", recordId);
                return null;
            }

            if (!"进行中".equals(record.getStatus())) {
                log.warn("运动记录状态不正确: recordId={}, status={}", recordId, record.getStatus());
                return null;
            }

            // 设置结束时间和状态
            record.setEndTime(LocalDateTime.now());
            record.setStatus("已完成");
            record.setAvgHeartRate(avgHeartRate);
            record.setMaxHeartRate(maxHeartRate);
            record.setAvgSpeed(avgSpeed);
            record.setMaxSpeed(maxSpeed);

            // 计算运动时长
            record.calculateDuration();

            int updateResult = exerciseRecordMapper.update(record);
            if (updateResult <= 0) {
                log.error("更新运动记录失败: recordId={}", recordId);
                return null;
            }

            log.info("结束运动成功: recordId={}", recordId);
            return record;
        } catch (Exception e) {
            log.error("结束运动失败: recordId={}", recordId, e);
            return null;
        }
    }

    /**
     * 更新实时数据（供ZRDDS调用）
     */
    public void updateRealTimeData(Long userId, Double heartRate, Double speed) {
        try {
            // 获取用户进行中的运动记录
            List<ExerciseRecord> ongoingRecords = exerciseRecordMapper.selectByUserIdAndStatus(userId, "进行中");
            if (!ongoingRecords.isEmpty()) {
                ExerciseRecord record = ongoingRecords.get(0);
                // 这里可以更新实时数据，比如存储到缓存或临时表中
                log.debug("更新实时数据: recordId={}, heartRate={}, speed={}", record.getId(), heartRate, speed);
            }
        } catch (Exception e) {
            log.error("更新实时数据失败: userId={}", userId, e);
        }
    }

}
